EKS Auto Mode で Pod Security Standards や Pod Security Admission を使って特権コンテナの起動を制限する

EKS Auto Mode で Pod Security Standards や Pod Security Admission を使って特権コンテナの起動を制限する

こんにちは。枡川です。
EKS Auto Mode を利用することで、ノード管理(スケーリング、パッチ管理)を AWS に任せることが可能です。

Amazon EKS Auto Mode is responsible for creating, deleting, and patching EC2 Instances. You are responsible for the containers and pods deployed on the instance.
https://docs.aws.amazon.com/eks/latest/userguide/automode-learn-instances.html

一方で、AWS マネージドではあるものの、実態としては EC2 であり、特権コンテナを作成することが可能です。
この点は特権コンテナを作成できない Fargate とは明確に違う点なので、注意が必要です。

This parameter is not supported for Windows containers or tasks using the Fargate launch type.
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

自由度が高いという点ではメリットかもしれませんが、コンテナ侵害時の影響範囲を減らすために多くの場合では特権コンテナを使うべきではありません。

https://www.trendmicro.com/ja_jp/research/20/a/why-it-is-dangerous-to-run-Docker-containers-in-privileged-mode.html

そのため、Pod Security Standards(PSS)/Pod Security Admission(PSA)を適切に設定することで、不必要な特権コンテナの起動を防ぐような設定が推奨されます。
このことは AWS 公式ドキュメントにも記載されています。

Implement pod security standards appropriate for your workloads.
https://docs.aws.amazon.com/eks/latest/userguide/auto-security.html#auto-security-bp

Pod Security Admission(PSA) と Pod Security Standards(PSS) について

軽く Pod Security Admission(PSA)Pod Security Standards (PSS) について述べておきます。
PSS は下記 3 つのセキュリティポリシーとそれらに属するコントロール(チェック項目)を定義しています。

  • Privileged (unsecure)
  • Baseline (secure)
  • Restricted (highly secure)

特権コンテナは Privileged では許容されるものの、Baseline と Restricted のポリシーでは許容されません。
PSS はあくまでポリシーを定義しますが、PSA と呼ばれる設定の中で Pod の起動をブロックするか、警告を出すかといった違反時の対応を選択可能です。
この時、下記 3 つの対応を選択することが可能です。

  • Enforce (ポリシーに違反する Pod の起動をさせない)
  • Audit (ポリシーに違反する Pod が起動された時に監査ログに出力する)
  • Warn (ポリシーに違反する Pod が起動された時にコンソールに警告に出力する)

実際にはこの 2 つの設定を組み合わせて利用していく形になります。

EKS Auto Mode で特権コンテナを起動してみる

v1.31 で Auto Mode を有効化した EKS を作成します。
こちらの作成手順は他記事で取り上げているので、今回は省略します。

マネジメントコンソールで作成したパターン。

https://dev.classmethod.jp/articles/eks-auto-mode/

eksctl で作成したパターン。

https://dev.classmethod.jp/articles/create-auto-mode-eks-cluster-with-eksctl/

Terraform で作成したパターン。

https://dev.classmethod.jp/articles/create-eks-auto-mode-cluster-by-terraform/

Nginx のコンテナを特権コンテナとして起動します。
securityContext 設定を行うことで、特権コンテナとして起動することが可能です。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: default
  name: nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx
    spec:
      containers:
        - image: nginx:1.14.2
          imagePullPolicy: Always
          name: nginx
          ports:
            - containerPort: 80
          securityContext:
            privileged: true
          resources:
            requests:
              cpu: "0.5"

コンテナに乗り込んで確認すると、ホスト OS の cgroup ディレクトリに書き込み権限 (rw) があることがわかります。

root@nginx-7d758f5c69-mmwcr:/# mount | grep cgroup
cgroup on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel)

ちなみに特権コンテナでない場合は、読み取り権限です。

root@nginx-64549c5599-7pmgg:/# mount | grep cgroup
cgroup on /sys/fs/cgroup type cgroup2 (ro,nosuid,nodev,noexec,relatime,seclabel)

意図せず特権コンテナで起動することで、ホストへのエスケープを許してしまう可能性があるので可能な限り特権コンテナは使いたくないですね。

https://www.creationline.com/tech-blog/cloudnative/aquasecurity/45972

PSA/PSS を設定して、特権コンテナの起動を禁止する

まず、PSA/PSS を指定して名前空間 app を作成します。
baseline を満たさない Pod は起動できないようにします。

apiVersion: v1
kind: Namespace
metadata:
  name: app
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

名前空間として app を指定して、Pod を作成してみます。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: app
  name: nginx
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx
    spec:
      containers:
        - image: nginx:1.14.2
          imagePullPolicy: Always
          name: nginx
          ports:
            - containerPort: 80
          securityContext:
            privileged: true
          resources:
            requests:
              cpu: "0.5"

kubectl apply を実行したタイミングでコンソールに警告が出ます。

% kubectl apply -f deployment.yaml
Warning: would violate PodSecurity "restricted:latest": privileged (container "nginx" must not set securityContext.privileged=true), allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
deployment.apps/nginx created

Deployment は作成されています。

% kubectl get deployment -n app
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   0/1     0            0           115s

一方で Pod は作成されていません。

% kubectl get pod -n app
No resources found in app namespace.

上手くブロックできてますね!
また、securityContextfalse に変更することで無事デプロイできることも確認できました。

% kubectl get pod -n app
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6b5649c4f8-fql2h   1/1     Running   0          8s

まとめ

EKS Auto Mode で PSS を利用して特権コンテナの起動を禁止してみました。
Auto Mode ではノードが AWS 管理にはなるものの、全く意識しなくて良いわけではないので注意して使いたいです。
下記ページに EKS Auto Mode を使う際にセキュリティ面で何を考慮するべきかがまとまっているため、利用する前に一読をおすすめします!

https://docs.aws.amazon.com/eks/latest/userguide/auto-security.html

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.